﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Word;
using System.Windows.Forms;

namespace FinalTemplate
{
    class ControlValueBinder
    {
        Facturae facturae;
        ContentControls controles;
        ThirdPartyType thirdParty;
        Document document;
        BatchType batch;

        BusinessType sellerParty;
        BusinessType buyerParty;

        InvoiceType invoice;
        InvoiceHeaderType invoiceHeader;
        InvoiceIssueDataType invoiceIssueData;
        char[] x = { '\r', '\a', '\n' };
        int t1, t2, t3, t4, t5, t6, t7;
        double bruto, abono, desc, baseImp, gastosEnvio, iva, total;

        string control = "";

        public ControlValueBinder(Facturae facturae, Document document)
        {
            try
            {
                //Root
                this.facturae = facturae;
                this.document = document;
                this.controles = document.ContentControls;      
                         

                //FileHeader Elements
                getControl(ControlList.Tag.InvoiceIssuerType).Range.Text = facturae.FileHeader.InvoiceIssuerType.ToString("g");
                getThirdParty(facturae.FileHeader.ThirdParty);
                getSellerParty(facturae.Parties.SellerParty );
                getBuyerParty(facturae.Parties.BuyerParty);
            
                facturae.Invoices.Add(getInvoice());
                getBatch(facturae.FileHeader.Batch);
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

        }



        #region Private Methods


        /*MÉTODOS NECESARIOS PARA CREAR LA ESTRUCTURA THIRDPARTY */


        // se utiliza en caso del que el emisor de la factura sea un tercero
        private void getThirdParty(ThirdPartyType thirdParty)
        {
            try
            {
                if (thirdParty != null)
                {

                    if (facturae.FileHeader.InvoiceIssuerType.Equals(InvoiceIssuerTypeType.TE))
                    {
                        getControl(ControlList.Tag.TH_PersonTypeCode).Range.Text = thirdParty.TaxIdentification.PersonTypeCode.ToString("g");
                        getControl(ControlList.Tag.TH_ResidenceTypeCode).Range.Text = thirdParty.TaxIdentification.ResidenceTypeCode.ToString("g");
                        getControl(ControlList.Tag.TH_TaxIdentificationNumber).Range.Text = thirdParty.TaxIdentification.TaxIdentificationNumber;
                        getTypePerson(Parent.ThirdParty, thirdParty.TaxIdentification);
                    }
                }
            }
            catch (Exception) { }
            
        }

        //se utiliza en caso de ser personería juridica
        private void getLegalEntity(Parent parent)
        {
            LegalEntityType legalEntity = null;

            try{
                switch (parent)
                {
                    case Parent.ThirdParty:
                        legalEntity = (LegalEntityType)facturae.FileHeader.ThirdParty.Item;
                        getControl(ControlList.Tag.TH_CorporateName).Range.Text = legalEntity.CorporateName;
                        //getControl(ControlList.Tag.TH_TradeName).Range.Text=legalEntity.TradeName; 
                        //getRegistrationData(parent,legalEntity);
                        getAddress(parent,legalEntity.Item);
                        getContacDetails(parent,legalEntity.ContactDetails); break;

                    case Parent.SellerParty:
                        legalEntity = (LegalEntityType)facturae.Parties.SellerParty.Item;
                        getControl(ControlList.Tag.SP_CorporateName).Range.Text = legalEntity.CorporateName;
                        getControl(ControlList.Tag.SP_TradeName).Range.Text=legalEntity.TradeName; 
                        getRegistrationData(parent,legalEntity);
                        getAddress(parent, getControl(ControlList.Tag.SP_CountryCode));
                        getContacDetails(parent,legalEntity.ContactDetails); break;

                    case Parent.BuyerParty:
                        legalEntity = (LegalEntityType)facturae.Parties.BuyerParty.Item;
                        getControl(ControlList.Tag.BP_CorporateName).Range.Text = legalEntity.CorporateName;
                        getControl(ControlList.Tag.BP_TradeName).Range.Text=legalEntity.TradeName; 
                        getRegistrationData(parent,legalEntity);
                       getAddress(Parent.ThirdParty, getControl(ControlList.Tag.BP_CountryCode));
                      getContacDetails(parent,legalEntity.ContactDetails); break;
                }
            }catch(NullReferenceException){}

            }

            
        

        //datos registrales
        private void getRegistrationData(Parent parent,LegalEntityType legalEntity)
        {
            RegistrationDataType registracionData = legalEntity.RegistrationData;

            try
            {
                switch (parent)
                {

                    case Parent.ThirdParty:

                        getControl(ControlList.Tag.TH_Book).Range.Text = registracionData.Book;
                        getControl(ControlList.Tag.TH_RegisterOfCompaniesLocation).Range.Text=registracionData.RegisterOfCompaniesLocation;
                        getControl(ControlList.Tag.TH_Sheet).Range.Text = registracionData.Sheet;
                        getControl(ControlList.Tag.TH_Folio).Range.Text=registracionData.Folio;
                        getControl(ControlList.Tag.TH_Section).Range.Text = registracionData.Section;
                        getControl(ControlList.Tag.TH_Volume).Range.Text= registracionData.Volume;
                        getControl(ControlList.Tag.TH_AdditionalRegistrationData).Range.Text= registracionData.AdditionalRegistrationData; break;

                    case Parent.SellerParty:

                        getControl(ControlList.Tag.SP_Book).Range.Text = registracionData.Book;
                        getControl(ControlList.Tag.SP_RegisterOfCompaniesLocation).Range.Text = registracionData.RegisterOfCompaniesLocation;
                        getControl(ControlList.Tag.SP_Sheet).Range.Text = registracionData.Sheet;
                        getControl(ControlList.Tag.SP_Folio).Range.Text = registracionData.Folio;
                        getControl(ControlList.Tag.SP_Section).Range.Text = registracionData.Section;
                        getControl(ControlList.Tag.SP_Volume).Range.Text = registracionData.Volume;
                        getControl(ControlList.Tag.SP_AdditionalRegistrationData).Range.Text = registracionData.AdditionalRegistrationData; break;

                    case Parent.BuyerParty:

                        getControl(ControlList.Tag.BP_Book).Range.Text = registracionData.Book;
                        getControl(ControlList.Tag.BP_RegisterOfCompaniesLocation).Range.Text = registracionData.RegisterOfCompaniesLocation;
                        getControl(ControlList.Tag.BP_Sheet).Range.Text = registracionData.Sheet;
                        getControl(ControlList.Tag.BP_Folio).Range.Text = registracionData.Folio;
                        getControl(ControlList.Tag.BP_Section).Range.Text = registracionData.Section;
                        getControl(ControlList.Tag.BP_Volume).Range.Text = registracionData.Volume;
                        getControl(ControlList.Tag.BP_AdditionalRegistrationData).Range.Text = registracionData.AdditionalRegistrationData; break;
                }
            }
            catch (NullReferenceException) { }
            
        }

        //direccion en España
        private AddressType getAddressInSpain(Parent parent,AddressType addressInSpain)
        {
           
            switch (parent)
            {
                case Parent.ThirdParty:

                    getControl(ControlList.Tag.TH_Address).Range.Text = addressInSpain.Address;
                    getControl(ControlList.Tag.TH_PostCode).Range.Text = addressInSpain.PostCode;
                    getControl(ControlList.Tag.TH_Town).Range.Text = addressInSpain.Town ;
                    getControl(ControlList.Tag.TH_Province).Range.Text= addressInSpain.Province ;
                    getControl(ControlList.Tag.TH_CountryCode).Range.Text=addressInSpain.CountryCode.ToString("g") ; break;

                case Parent.SellerParty:
                    
                    getControl(ControlList.Tag.SP_Address).Range.Text = addressInSpain.Address;
                    getControl(ControlList.Tag.SP_PostCode).Range.Text = addressInSpain.PostCode;
                    getControl(ControlList.Tag.SP_Town).Range.Text = addressInSpain.Town;
                    getControl(ControlList.Tag.SP_Province).Range.Text = addressInSpain.Province;
                    getControl(ControlList.Tag.SP_CountryCode).Range.Text = addressInSpain.CountryCode.ToString("g"); break;

                case Parent.BuyerParty:
                    
                    getControl(ControlList.Tag.BP_Address).Range.Text = addressInSpain.Address;
                    getControl(ControlList.Tag.BP_PostCode).Range.Text = addressInSpain.PostCode;
                    getControl(ControlList.Tag.BP_Town).Range.Text = addressInSpain.Town;
                    getControl(ControlList.Tag.BP_Province).Range.Text = addressInSpain.Province;
                    getControl(ControlList.Tag.BP_CountryCode).Range.Text = addressInSpain.CountryCode.ToString("g"); break;

            }
            return addressInSpain;

        }

        //direccion en el extranjero
        private OverseasAddressType getOverSeasAddres(Parent parent,object address)
        {

            OverseasAddressType overSeasAddress = (OverseasAddressType) address;

            switch (parent)
            {
                case Parent.ThirdParty:

                    getControl(ControlList.Tag.TH_Address).Range.Text=overSeasAddress.Address;
                    getControl(ControlList.Tag.TH_PostCode).Range.Text= overSeasAddress.PostCodeAndTown;
                    getControl(ControlList.Tag.TH_Town).Range.Text = overSeasAddress.PostCodeAndTown;
                    getControl(ControlList.Tag.TH_Province).Range.Text=overSeasAddress.Province;
                    getControl(ControlList.Tag.TH_CountryCode).Range.Text = overSeasAddress.CountryCode.ToString("g"); break;

                case Parent.SellerParty:


                    getControl(ControlList.Tag.SP_Address).Range.Text = overSeasAddress.Address;
                    getControl(ControlList.Tag.SP_PostCode).Range.Text = overSeasAddress.PostCodeAndTown;
                    getControl(ControlList.Tag.SP_Town).Range.Text = overSeasAddress.PostCodeAndTown;
                    getControl(ControlList.Tag.SP_Province).Range.Text = overSeasAddress.Province;
                    getControl(ControlList.Tag.SP_CountryCode).Range.Text = overSeasAddress.CountryCode.ToString("g"); break;

                case Parent.BuyerParty:


                    getControl(ControlList.Tag.BP_Address).Range.Text = overSeasAddress.Address;
                    getControl(ControlList.Tag.BP_PostCode).Range.Text = overSeasAddress.PostCodeAndTown;
                    getControl(ControlList.Tag.BP_Town).Range.Text = overSeasAddress.PostCodeAndTown;
                    getControl(ControlList.Tag.BP_Province).Range.Text = overSeasAddress.Province;
                    getControl(ControlList.Tag.BP_CountryCode).Range.Text = overSeasAddress.CountryCode.ToString("g"); break;
            }
            return overSeasAddress;

        }

        //determina el tipo de direccion, nacional o extranjera
        private void getAddress(Parent parent, object item)
        {
            AddressType add = (AddressType)item;

            if (add.CountryCode.Equals(CountryType.ESP.ToString()))
                getAddressInSpain(parent,add);
            else
                getOverSeasAddres(parent,add);            

        }

        // detalles de contacto
        private void getContacDetails(Parent parent, ContactDetailsType contactDetails)
        {
            
            switch (parent)
            {
                case Parent.ThirdParty:

                    getControl(ControlList.Tag.TH_Telephone).Range.Text=contactDetails.Telephone ;
                    //getControl(ControlList.Tag.TH_TeleFax).Range.Text=contactDetails.TeleFax;
                    //getControl(ControlList.Tag.TH_WebAddress).Range.Text=contactDetails.WebAddress;
                    getControl(ControlList.Tag.TH_Email).Range.Text = contactDetails.ElectronicMail; break;
                    //getControl(ControlList.Tag.TH_ContactPersons).Range.Text=contactDetails.ContactPersons;
                    //getControl(ControlList.Tag.TH_CnoCnae).Range.Text=contactDetails.CnoCnae;
                    //getControl(ControlList.Tag.TH_INETownCode).Range.Text=contactDetails.INETownCode;
                    //getControl(ControlList.Tag.TH_AdditionalContactDetails).Range.Text=contactDetails.AdditionalContactDetails; break;

                case Parent.SellerParty:
                    getControl(ControlList.Tag.SP_Telephone).Range.Text = contactDetails.Telephone;
                    //getControl(ControlList.Tag.SP_TeleFax).Range.Text = contactDetails.TeleFax;
                    //getControl(ControlList.Tag.SP_WebAddress).Range.Text = contactDetails.WebAddress;
                    getControl(ControlList.Tag.SP_email).Range.Text = contactDetails.ElectronicMail; break;
                    //getControl(ControlList.Tag.SP_ContactPersons).Range.Text = contactDetails.ContactPersons;
                    //getControl(ControlList.Tag.SP_CnoCnae).Range.Text = contactDetails.CnoCnae;
                    //getControl(ControlList.Tag.SP_INETownCode).Range.Text = contactDetails.INETownCode;
                    //getControl(ControlList.Tag.SP_AdditionalContactDetails).Range.Text = contactDetails.AdditionalContactDetails; break;

                case Parent.BuyerParty:

                    getControl(ControlList.Tag.BP_Telephone).Range.Text = contactDetails.Telephone;
                    //getControl(ControlList.Tag.BP_TeleFax).Range.Text = contactDetails.TeleFax;
                    //getControl(ControlList.Tag.BP_WebAddress).Range.Text = contactDetails.WebAddress;
                    getControl(ControlList.Tag.BP_ElectronicMail).Range.Text = contactDetails.ElectronicMail; break;
                    getControl(ControlList.Tag.BP_ContactPersons).Range.Text = contactDetails.ContactPersons;
                    //getControl(ControlList.Tag.BP_CnoCnae).Range.Text = contactDetails.CnoCnae;
                    //getControl(ControlList.Tag.BP_INETownCode).Range.Text = contactDetails.INETownCode;
                    //getControl(ControlList.Tag.BP_AdditionalContactDetails).Range.Text = contactDetails.AdditionalContactDetails; break;


            }
           
        }

        //se utiliza en caso de ser persona Física
        private void getIndividual(Parent parent)
        {
            IndividualType individual = new IndividualType();

            switch (parent)
            {

                case Parent.ThirdParty:

                    getControl(ControlList.Tag.TH_Name).Range.Text=individual.Name;
                    getControl(ControlList.Tag.TH_FirstSurname).Range.Text = individual.FirstSurname;
                   //getControl(ControlList.Tag.TH_SecondSurname).Range.Text= individual.SecondSurname;
                   getAddress(parent, getControl(ControlList.Tag.TH_CountryCode));
                   getContacDetails(parent, individual.ContactDetails); break;

                case Parent.SellerParty:

                    getControl(ControlList.Tag.SP_Name).Range.Text = individual.Name;
                    getControl(ControlList.Tag.SP_FirstSurname).Range.Text = individual.FirstSurname;
                    //getControl(ControlList.Tag.SP_SecondSurname).Range.Text = individual.SecondSurname;
                    getAddress(parent, getControl(ControlList.Tag.SP_CountryCode));
                    getContacDetails(parent, individual.ContactDetails); break;

                case Parent.BuyerParty:
                    getControl(ControlList.Tag.BP_Name).Range.Text = individual.Name;
                    getControl(ControlList.Tag.BP_FirstSurname).Range.Text = individual.FirstSurname;
                    //getControl(ControlList.Tag.BP_SecondSurname).Range.Text = individual.SecondSurname;
                    getAddress(parent, getControl(ControlList.Tag.BP_CountryCode));
                    getContacDetails(parent, individual.ContactDetails); break;
            }
            
        }

        // determina si es persona física o jurídica
        private void getTypePerson(Parent parent, TaxIdentificationType taxIdentification)
        {
            if (!taxIdentification.Equals(null))
            {
                if (taxIdentification.PersonTypeCode.Equals(PersonTypeCodeType.J))

                    getLegalEntity(parent);
                else
                    getIndividual(parent);
            }
            
        }


        /*MÉTODOS NECESARIOS PARA CREAR LA ESTRUCTURA BATCH */


        private void getBatch(BatchType batch)
        {

            getControl(ControlList.Tag.InvIssue_InvoiceCurrencyCode).Range.Text = batch.InvoiceCurrencyCode.ToString("g");            
                 
        }

        //private AmountType getAmount(Parent parent, AmountType amount)
        //{
           
        //    switch (parent)
        //    {
                
        //        case Parent.TaxableBase:

        //            if (string.IsNullOrEmpty(getControl(ControlList.Tag.TaxO_TaxableBase_TotalAmount)))
        //                totalAmount.TotalAmount = 0.0d;
        //            else
        //            {
        //                double taxableBase = double.Parse(document.Tables[t5].Rows[2].Cells[3].Range.Text.Trim(x).Trim()) - double.Parse(document.Tables[5].Rows[4].Cells[3].Range.Text.Trim(x).Trim());
        //                totalAmount.TotalAmount = taxableBase * double.Parse(document.Tables[5].Rows[4].Cells[2].Range.Text.Trim(x).Trim());


        //                if (!batch.InvoiceCurrencyCode.Equals(CurrencyCodeType.EUR))
        //                {
        //                    totalAmount.EquivalentInEurosSpecified = true;
        //                    totalAmount.EquivalentInEuros = double.Parse(getControl(ControlList.Tag.TaxO_TaxableBase_EquivalentInEuros));
        //                }
        //            } break;

        //        case Parent.TaxAmount:
        //            if (string.IsNullOrEmpty(getControl(ControlList.Tag.TaxO_TaxAmount_TotalAmount)))
        //                totalAmount.TotalAmount = 0.0d;
        //            else
        //            {
        //                totalAmount.TotalAmount = double.Parse(getControl(ControlList.Tag.TaxO_TaxAmount_TotalAmount));

        //                if (!batch.InvoiceCurrencyCode.Equals(CurrencyCodeType.EUR))
        //                {
        //                    totalAmount.EquivalentInEurosSpecified = true;
        //                    totalAmount.EquivalentInEuros = double.Parse(getControl(ControlList.Tag.TaxO_TaxAmount_EquivalentInEuros));
        //                }
        //            } break;

        //    }
        //    return totalAmount;
        //}


        /*MÉTODOS NECESARIOS PARA CREAR LA ESTRUCTURA PARTIES */

        private void getSellerParty(BusinessType sellerParty)
        {
            getControl(ControlList.Tag.SP_PersonTypeCode).Range.Text= sellerParty.TaxIdentification.PersonTypeCode.ToString("g") ;
            getControl(ControlList.Tag.SP_ResidenceTypeCode).Range.Text=sellerParty.TaxIdentification.ResidenceTypeCode.ToString("g");
            getControl(ControlList.Tag.SP_TaxIdentificationNumber).Range.Text=sellerParty.TaxIdentification.TaxIdentificationNumber;
            getControl(ControlList.Tag.SP_PartyIdentification).Range.Text=sellerParty.PartyIdentification  ;
            sellerParty.AdministrativeCentres = null;
            getTypePerson(Parent.SellerParty, sellerParty.TaxIdentification);
            
        }

        private void getBuyerParty(BusinessType buyerParty)
        {

            getControl(ControlList.Tag.BP_PersonTypeCode).Range.Text = buyerParty.TaxIdentification.PersonTypeCode.ToString("g");
            getControl(ControlList.Tag.BP_ResidenceTypeCode).Range.Text = buyerParty.TaxIdentification.ResidenceTypeCode.ToString("g");
            getControl(ControlList.Tag.BP_TaxIdentificationNumber).Range.Text = buyerParty.TaxIdentification.TaxIdentificationNumber;
            getControl(ControlList.Tag.BP_PartyIdentification).Range.Text = buyerParty.PartyIdentification;
            buyerParty.AdministrativeCentres = null;
            getTypePerson(Parent.BuyerParty, buyerParty.TaxIdentification);
        }

        //private List<AdministrativeCentreType> AddAdministrativeCentre(Parent parent, List<AdministrativeCentreType> administrativeCentres)
        //{
        //    if (administrativeCentres == null)
        //        administrativeCentres = new List<AdministrativeCentreType>();
        //    AdministrativeCentreType administrativeCentre = new AdministrativeCentreType();
        //    administrativeCentre.CentreCode = null;
        //    administrativeCentre.RoleTypeCode = RoleTypeCodeType.Item01;
        //    administrativeCentre.Name = null;
        //    administrativeCentre.FirstSurname = null;
        //    administrativeCentre.SecondSurname = null;
        //    administrativeCentre.Item = getAddress(parent, CountryType.ESP.ToString());
        //    administrativeCentre.ContactDetails = getContacDetails(parent);
        //    administrativeCentre.PhysicalGLN = null;
        //    administrativeCentre.LogicalOperationalPoint = null;
        //    administrativeCentres.Add(administrativeCentre);

        //    return administrativeCentres;

        //}

        /*MÉTODOS NECESARIOS PARA CREAR LA ESTRUCTURA INVOICES */

        private InvoiceType getInvoice()
        {
            try
            {
                invoice = new InvoiceType();
                getInvoiceHeader(invoice.InvoiceHeader);
                getInvoiceIssueData(invoice.InvoiceIssueData );
                invoice.TaxesOutputs = getTaxesOutputs(invoice.TaxesOutputs);
                invoice.TaxesWithheld = null;
                invoice.InvoiceTotals = getInvoiceTotals();
                invoice.Items = getItems(invoice.Items);
                getPaymentDetails(invoice.PaymentDetails);
                invoice.AdditionalData = getAdditionaData();
            }
            catch (Exception e)
            {
                throw e;
            }
            return invoice;
        }

        private AdditionalDataType getAdditionaData()
        {
            AdditionalDataType additionalData = null;
            if (control != null)
            {

                additionalData = new AdditionalDataType();
                additionalData.InvoiceAdditionalInformation = document.Tables[t4].Rows[2].Range.Text.Trim(x).Trim();
            }

            return additionalData;

        }

        private void getPaymentDetails(List<InstallmentType> paymentDetails)
        {
            if (paymentDetails!= null)
            {
                InstallmentType installment = paymentDetails[1];
                getControl(ControlList.Tag.Inst_InstallmentDueDate).Range.Text = installment.InstallmentDueDate.ToString();
                getControl(ControlList.Tag.Inst_InstallmentAmount).Range.Text = installment.InstallmentAmount.ToString();
                getControl(ControlList.Tag.Inst_PaymentMeans).Range.Text = installment.PaymentMeans.ToString("g");

            }

            

        }

        private List<InvoiceLineType> getItems(List<InvoiceLineType> items)
        {
            if (items == null)
                items = new List<InvoiceLineType>();


            /*recorremos todas las filas de la tabla para agregar los registros a la lista de itemes*/

            for (int i = 3; i < document.Tables[2].Rows.Count; i++)
            {

                InvoiceLineType item = new InvoiceLineType();
                string descripcion = document.Tables[t2].Rows[i].Cells[2].Range.Text.Trim(x).Trim();
                double Quantity = double.Parse(document.Tables[t2].Rows[i].Cells[3].Range.Text.Trim(x).Trim());
                double UnitPriceWithoutTax = double.Parse(document.Tables[t2].Rows[i].Cells[4].Range.Text.Trim(x).Trim());
                double discountRate = double.Parse(document.Tables[t2].Rows[i].Cells[5].Range.Text.Trim(x).Trim());
                double discountAmount = (Quantity * UnitPriceWithoutTax) * discountRate / 100;
                double taxRate = double.Parse(document.Tables[t2].Rows[i].Cells[6].Range.Text.Trim(x).Trim());
                double baseImponible = (Quantity * UnitPriceWithoutTax) - discountAmount;
                double montoImp = baseImponible * taxRate / 100;
                double totalImport = baseImponible - montoImp;
                DateTime transactionDate = DateTime.Parse(document.Tables[t2].Rows[i].Cells[1].Range.Text.Trim(x).Trim());


                item.ItemDescription = descripcion;
                item.Quantity = Quantity;
                item.UnitPriceWithoutTax = UnitPriceWithoutTax;


                //descuentos por linea 
                DiscountType discountByLine = new DiscountType();
                discountByLine.DiscountReason = "Descuento";
                double discountRate = double.Parse(document.Tables[t3].Rows[i].Cells[2].Range.Text.Trim(x).Trim());
                object[] dr = { discountRate };
                discountByLine.DiscountRate = string.Format(num, "{0:0.0000}", dr); 
                
                discountByLine.DiscountAmount = discountAmount;
                discountByLine.DiscountRateSpecified = true;
                item.DiscountsAndRebates = new List<DiscountType>();
                item.DiscountsAndRebates.Add(discountByLine);

                //impuestos por linea
                InvoiceLineTypeTax tax = new InvoiceLineTypeTax();
                tax.TaxTypeCode = TaxTypeCodeType.Item01;
                tax.TaxRate = string.Format("{0:0.00}", taxRate);
                tax.TaxableBase = new AmountType();
                tax.TaxableBase.TotalAmount = baseImponible;
                if (!getControl(ControlList.Tag.InvIssue_InvoiceCurrencyCode).Equals("EUR"))
                {
                    tax.TaxableBase.EquivalentInEuros = baseImponible * 1.22;
                    tax.TaxableBase.EquivalentInEurosSpecified = true;
                }



                item.TaxesOutputs = new List<InvoiceLineTypeTax>();
                item.TaxesOutputs.Add(tax);

                item.TotalCost = baseImponible + baseImponible * taxRate;

                item.TransactionDateSpecified = true;
                item.TransactionDate = transactionDate;
                items.Add(item);

            }
            return items;
        }



        private void getDeliveryNotes(List<DeliveryNoteType> deliveryNotes)
        {
            if (deliveryNotes != null)
            {
                deliveryNotes = new List<DeliveryNoteType>();
                DeliveryNoteType deliveryNote = deliveryNotes[1];
                getControl(ControlList.Tag.DeliveryNote_DeliveryNoteNumber).Range.Text = deliveryNote.DeliveryNoteNumber;
            }
        }

        private InvoiceTotalsType getInvoiceTotals()
        {
            InvoiceTotalsType invoiceTotals = new InvoiceTotalsType();
            invoiceTotals.TotalGrossAmount = ((double)Math.Round(bruto, 2));
            invoiceTotals.TotalGrossAmountBeforeTaxes = ((double)Math.Round(baseImp, 2));
            invoiceTotals.TotalTaxOutputs = ((double)Math.Round(iva, 2));
            invoiceTotals.TotalTaxesWithheld = 0.00;
            invoiceTotals.InvoiceTotal = ((double)Math.Round((baseImp + iva), 2));
            invoiceTotals.TotalOutstandingAmount = ((double)Math.Round((baseImp + iva), 2));
            invoiceTotals.TotalExecutableAmount = ((double)Math.Round((baseImp + iva), 2));
            invoiceTotals.TotalGeneralDiscounts = desc;

            return invoiceTotals;
        }

        private List<DiscountType> getGeneralDiscounts(List<DiscountType> generalDiscounts)
        {

            for (int i = 3; i < document.Tables[t3].Rows.Count; i++)
            {
                if (generalDiscounts == null)
                    generalDiscounts = new List<DiscountType>();

                DiscountType generalDiscount = new DiscountType();
                generalDiscount.DiscountReason = document.Tables[t3].Rows[i].Cells[1].Range.Text.Trim(x).Trim();

                generalDiscount.DiscountRate = double.Parse(document.Tables[t3].Rows[i].Cells[2].Range.Text.Trim(x).Trim());
                generalDiscount.DiscountAmount = double.Parse(document.Tables[t3].Rows[i].Cells[3].Range.Text.Trim(x).Trim());
                generalDiscount.DiscountRateSpecified = true;
                generalDiscounts.Add(generalDiscount);
            }
            return generalDiscounts;

        }

        private List<TaxOutputType> getTaxesOutputs(List<TaxOutputType> taxesOutputs)
        {

            if (taxesOutputs == null)
                taxesOutputs = new List<TaxOutputType>();


            for (int i = 3; i < document.Tables[t2].Rows.Count; i++)
            {
                double taxRate = 0.00d;
                double Quantity = double.Parse(document.Tables[t2].Rows[i].Cells[3].Range.Text.Trim(x).Trim());
                double UnitPriceWithoutTax = double.Parse(document.Tables[t2].Rows[i].Cells[4].Range.Text.Trim(x).Trim());
                double discountRate = (double)Math.Round(double.Parse(document.Tables[t2].Rows[i].Cells[5].Range.Text.Trim(x).Trim()), 4);
                double discountAmount = (Quantity * UnitPriceWithoutTax) * discountRate / 100;
                taxRate = (double)Math.Round(double.Parse(document.Tables[t2].Rows[i].Cells[6].Range.Text.Trim(x).Trim()), 2);
                double baseImponible = (double)Math.Round((Quantity * UnitPriceWithoutTax) - discountAmount, 2);
                double montoImp = (double)Math.Round((baseImponible * taxRate), 2);


                if (taxesOutputs.Count <= 0)
                {
                    taxesOutputs.Add(getTax(baseImponible, taxRate, montoImp));
                }
                else
                {
                    bool exist = false; int j;
                    for (j = 0; j < taxesOutputs.Count; j++)
                    {
                        if (taxesOutputs[j].TaxRate == taxRate.ToString())
                        {
                            exist = true; break;
                        }
                    }
                    if (exist)
                    {

                        taxesOutputs[j].TaxableBase.TotalAmount += (double)Math.Round(baseImponible, 2);
                        if (!getControl(ControlList.Tag.InvIssue_InvoiceCurrencyCode).Equals("EUR"))
                        {
                            taxesOutputs[j].TaxableBase.EquivalentInEuros = (double)Math.Round((baseImponible * 1.22), 2);
                            taxesOutputs[j].TaxableBase.EquivalentInEurosSpecified = true;
                        }

                        taxesOutputs[j].TaxAmount.TotalAmount += (double)Math.Round(montoImp, 2);
                        if (!getControl(ControlList.Tag.InvIssue_InvoiceCurrencyCode).Equals("EUR"))
                        {
                            taxesOutputs[j].TaxableBase.EquivalentInEuros = (double)Math.Round(montoImp * 1.22, 2);
                            taxesOutputs[j].TaxableBase.EquivalentInEurosSpecified = true;
                        }
                    }
                    else
                    {
                        taxesOutputs.Add(getTax(baseImponible, taxRate, montoImp));
                    }
                }

            }

            return taxesOutputs;
        }

        private TaxOutputType getTax(double baseImp, double taxRate, double montoImp)
        {
            TaxOutputType tax = new TaxOutputType();
            tax.TaxTypeCode = TaxTypeCodeType.Item01;
            tax.TaxRate = string.Format("{0:0.00}",taxRate);

            tax.TaxableBase = new AmountType();
            tax.TaxableBase.TotalAmount = (double)Math.Round(baseImp, 2);
            if (!getControl(ControlList.Tag.InvIssue_InvoiceCurrencyCode).Equals("EUR"))
            {
                tax.TaxableBase.EquivalentInEuros = (double)Math.Round(baseImp * 1.22, 2);
                tax.TaxableBase.EquivalentInEurosSpecified = true;
            }

            tax.TaxAmount = new AmountType();
            tax.TaxAmount.TotalAmount = (double)Math.Round(montoImp, 2);
            if (!getControl(ControlList.Tag.InvIssue_InvoiceCurrencyCode).Equals("EUR"))
            {
                tax.TaxableBase.EquivalentInEuros = (double)Math.Round(montoImp * 1.22, 2);
                tax.TaxableBase.EquivalentInEurosSpecified = true;
            }

            return tax;
        }

        private void getInvoiceIssueData(InvoiceIssueDataType invoiceIssueData)
        {

            getControl(ControlList.Tag.InvIssue_IssueDate).Range.Text = invoiceIssueData.IssueDate.ToString();
            getControl(ControlList.Tag.InvIssue_OperationDate).Range.Text = invoiceIssueData.OperationDate.ToString();
            getControl(ControlList.Tag.InvIssue_InvoiceCurrencyCode).Range.Text = invoiceIssueData.InvoiceCurrencyCode.ToString("g");
            getExchangeRateDetails(invoiceIssueData.ExchangeRateDetails);
            getControl(ControlList.Tag.InvIssue_TaxCurrencyCode).Range.Text = invoiceIssueData.TaxCurrencyCode.ToString("g");
            getControl(ControlList.Tag.InvIssue_LanguageName).Range.Text = invoiceIssueData.LanguageName.ToString("g");
            
        }

        private void getExchangeRateDetails(ExchangeRateDetailsType exchangeRateDetails)
        {
          
                if (!invoiceIssueData.InvoiceCurrencyCode.Equals(CurrencyCodeType.EUR))
                {
                    getControl(ControlList.Tag.InvIssue_ExchangeRateDetails_ExchangeRate).Range.Text = exchangeRateDetails.ExchangeRate.ToString();
                    getControl(ControlList.Tag.InvIssue_ExchangeRateDetails_ExchangeRateDate).Range.Text=exchangeRateDetails.ExchangeRateDate.ToString();
                }

             
        }

        private void getPlaceOfIssue( PlaceOfIssueType placeOfIssue)
        {
            
                    placeOfIssue = new PlaceOfIssueType();
                    getControl(ControlList.Tag.InvIssue_PlaceOfIssue_PostCode).Range.Text = placeOfIssue.PostCode;
                    getControl(ControlList.Tag.InvIssue_PlaceOfIssue_PlaceOfIssueDescription).Range.Text = placeOfIssue.PlaceOfIssueDescription;
                
        }

        private void getInvoicingPeriod(PeriodDates invoicingPeriod)
        {
                                   
            getControl(ControlList.Tag.InvIssue_InvoicingPeriod_StartDate).Range.Text=invoicingPeriod.StartDate.ToString();
            getControl(ControlList.Tag.InvIssue_InvoicingPeriod_EndDate).Range.Text = invoicingPeriod.EndDate.ToString();



        }

        private void getInvoiceHeader(InvoiceHeaderType invoiceHeader)
        {

            getControl(ControlList.Tag.IH_InvoiceNumber).Range.Text = invoiceHeader.InvoiceNumber;
            getControl(ControlList.Tag.IH_InvoiceSeriesCode).Range.Text = invoiceHeader.InvoiceSeriesCode;
            getControl(ControlList.Tag.IH_InvoiceDocumentType).Range.Text = invoiceHeader.InvoiceDocumentType.ToString("g");
            getControl(ControlList.Tag.IH_InvoiceClass).Range.Text = invoiceHeader.InvoiceClass.ToString("g");
            getCorrective(invoiceHeader.Corrective);

           
        }

        private void getCorrective(CorrectiveType corrective)
        {

            getControl(ControlList.Tag.CORR_InvoiceNumber).Range.Text = corrective.InvoiceNumber;
            getControl(ControlList.Tag.CORR_InvoiceSeriesCode).Range.Text = corrective.InvoiceSeriesCode;
            getControl(ControlList.Tag.CORR_ReasonCode).Range.Text = corrective.ReasonCode.ToString("g");
            getControl(ControlList.Tag.CORR_ReasonDescription).Range.Text = corrective.ReasonDescription.ToString("g");
            getControl(ControlList.Tag.CORR_TaxPeriod_StartDate).Range.Text = corrective.TaxPeriod.StartDate.ToString();
            getControl(ControlList.Tag.CORR_TaxPeriod_EndDate).Range.Text = corrective.TaxPeriod.EndDate.ToString();
            getControl(ControlList.Tag.CORR_CorrectionMethod).Range.Text = corrective.CorrectionMethod.ToString("g");
            getControl(ControlList.Tag.CORR_CorrectionMethodDescription).Range.Text = corrective.CorrectionMethodDescription.ToString("g");


        }




        #endregion


        #region Public Methods

        public Facturae getFacturae()
        {
            return facturae;
        }

        //public ContentControl getControl(ControlList.Tag tag)
        //{
        //    string value = null;
        //    if (string.IsNullOrEmpty(tag.ToString("g")))
        //        return value;
        //    foreach (ContentControl item in controles)
        //    {
        //        if (!string.IsNullOrEmpty(item.Tag))
        //        {
        //            if (item.Tag.Equals(tag.ToString("g")))
        //            {
        //                value = item.Range.Text;
        //                break;
        //            }
        //        }
        //    }

        //    return value;


        //}

        //private string controlValue(ControlList.Tag tag, string selectedItem)
        //{
        //    string value = "";

        //    if (string.IsNullOrEmpty(tag.ToString("g")))
        //        return value;

        //    /*buscamos el combobox indicado*/
        //    foreach (ContentControl item in controles)
        //    {
        //        if (!string.IsNullOrEmpty(item.Tag))
        //        {
        //            if (item.Tag.Equals(tag.ToString("g")))
        //            {
        //                /*si lo encontramos buscamos el valor correspondiente al texto seleccionado*/
        //                foreach (ContentControlListEntry entry in item.DropdownListEntries)
        //                {
        //                    if (!string.IsNullOrEmpty(item.Tag))
        //                    {
        //                        if (entry.Text.ToLower().Equals(selectedItem.ToLower()))
        //                        {
        //                            value = entry.Value; break;
        //                        }
        //                    }

        //                } break;
        //            }
        //        }
        //    }
        //    return value;
        //}

        private static double redondeo(double numero)
        {
            //BigDecimal bd = new BgDecimal(numero);
            //long numeroFinal = Math.Round(bd.movePointRight(2).doubleValue());
            long numeroFinal;
            if (numero >= 0)
            {
                numeroFinal = ((long)Math.Round((numero * (Math.Pow(10, 2)))));
            }
            else
            {
                numeroFinal = ((long)Math.Round((numero * (Math.Pow(10, -2)))));
            }
            return (double)numeroFinal / (100);
        }

        private ContentControl getControl(ControlList.Tag tag)
        {

            ContentControl control = null;
           

                foreach (ContentControl item in controles)
                {
                    if (!string.IsNullOrEmpty(item.Tag))
                    {
                        if (item.Tag.ToLower().Equals(tag.ToString("g").ToLower()))
                        {
                            control = item; break;
                        }
                    }
                }

                return control;
            }
            

        

        private void enumerateTables()
        {
            for (int i = 2; i <= document.Tables.Count; i++)
            {
                try
                {
                    string table = document.Tables[i].Rows[1].Range.Text.Trim(x).Trim();
                    t1 = 1;
                    switch (table)
                    {

                        case "DETALLES":
                            t2 = i; break;
                        case "DESCUENTOS":
                            t3 = i; break;
                        case "OBSERVACIONES":
                            t4 = i; break;
                        case "TOTALES":
                            t5 = i; break;
                        case "Tercero":
                            t6 = i; break;
                        case "VACIA":
                            t7 = i; break;

                    }
                }
                catch (Exception) { }
            }

        }

        #endregion

        #region Parser

        private InvoiceIssuerTypeType convertToInvoiceIssuerType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return InvoiceIssuerTypeType.EM;
            return (InvoiceIssuerTypeType)Enum.Parse(typeof(InvoiceIssuerTypeType), tag);
        }

        private PersonTypeCodeType convertToPersonType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return PersonTypeCodeType.F;
            return (PersonTypeCodeType)Enum.Parse(typeof(PersonTypeCodeType), tag);
        }

        private ResidenceTypeCodeType convertToResidenceType(string tag)
        {

            if (string.IsNullOrEmpty(tag))
                return ResidenceTypeCodeType.U;
            return (ResidenceTypeCodeType)Enum.Parse(typeof(ResidenceTypeCodeType), tag);
        }

        private CountryType convertToCountryType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return CountryType.ESP;
            return (CountryType)Enum.Parse(typeof(CountryType), tag);
        }

        private CurrencyCodeType convertToCurrencyType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return CurrencyCodeType.EUR;
            return (CurrencyCodeType)Enum.Parse(typeof(CurrencyCodeType), tag);
        }

        private InvoiceDocumentTypeType convertToInvoiceDocumentType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return InvoiceDocumentTypeType.AF;
            return (InvoiceDocumentTypeType)Enum.Parse(typeof(InvoiceDocumentTypeType), tag);
        }

        private InvoiceClassType convertToInvoiceClassType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return InvoiceClassType.CC;
            return (InvoiceClassType)Enum.Parse(typeof(InvoiceClassType), tag);
        }

        private ReasonCodeType convertToReasonCodeType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return ReasonCodeType.Item01;
            return (ReasonCodeType)Enum.Parse(typeof(ReasonCodeType), tag);
        }

        private ReasonDescriptionType convertToReasonDescriptionType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return ReasonDescriptionType.Baseimponible;
            return (ReasonDescriptionType)Enum.Parse(typeof(ReasonDescriptionType), tag);
        }

        private CorrectionMethodType convertToCorrectionMethodType(string tag)
        {

            if (string.IsNullOrEmpty(tag))
                return CorrectionMethodType.Item01;
            return (CorrectionMethodType)Enum.Parse(typeof(CorrectionMethodType), tag);
        }

        private CorrectionMethodDescriptionType convertToCorrectionMethodDescriptionType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return CorrectionMethodDescriptionType.AutorizadasporlaAgenciaTributaria;
            return (CorrectionMethodDescriptionType)Enum.Parse(typeof(CorrectionMethodDescriptionType), tag);
        }

        private TaxTypeCodeType convertToTaxTypeCodeType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return TaxTypeCodeType.Item01;
            return (TaxTypeCodeType)Enum.Parse(typeof(TaxTypeCodeType), tag);
        }

        private UnitOfMeasureType convertToUnitOfMeasureType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return UnitOfMeasureType.Item01;
            return (UnitOfMeasureType)Enum.Parse(typeof(UnitOfMeasureType), tag);
        }

        private LanguageCodeType convertToLanguageCodeType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return LanguageCodeType.es;
            return (LanguageCodeType)Enum.Parse(typeof(LanguageCodeType), tag);
        }

        private PaymentMeansType convertToPaymentMeansType(string tag)
        {
            if (string.IsNullOrEmpty(tag))
                return PaymentMeansType.Item01;
            return (PaymentMeansType)Enum.Parse(typeof(PaymentMeansType), tag);
        }



        private enum Parent
        {
            ThirdParty,
            SellerParty,
            BuyerParty,
            BatchTIA,
            BatchTOA,
            BatchTEA,
            TaxableBase,
            TaxAmount,
            ItemTB,
            ItemTA

        }


        #endregion

    }
}
